/*
 *    Copyright (c) 2018-2025, daoism All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: daoism
 */
package com.mkh.st.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mkh.st.admin.api.dto.*;
import com.mkh.st.admin.api.entity.*;
import com.mkh.st.admin.api.vo.BusinessPageVO;
import com.mkh.st.admin.api.vo.DataPermissionVO;
import com.mkh.st.admin.api.vo.SiteInfoVO;
import com.mkh.st.admin.mapper.*;
import com.mkh.st.admin.service.SysBusinessEntityService;
import com.mkh.st.admin.service.SysUserService;
import com.mkh.st.common.core.constant.CommonConstants;
import com.mkh.st.common.core.constant.enums.MenuEnum;
import com.mkh.st.common.core.constant.enums.ResultCodeEnum;
import com.mkh.st.common.core.constant.enums.ScopeEnum;
import com.mkh.st.common.core.exception.BizException;
import com.mkh.st.common.core.util.R;
import com.mkh.st.common.security.service.DaoismUser;
import com.mkh.st.common.security.util.SecurityUtils;
import com.mkh.st.warehouse.api.feign.IWarehouseProvider;
import com.mkh.st.warehouse.dto.DataPermissionDTO;
import com.mkh.st.warehouse.vo.WarehouseFeignVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 业务实体表
 *
 * @author daoism code generator
 * @date 2021-07-06 09:27:05
 */
@Service
@AllArgsConstructor
public class SysBusinessEntityServiceImpl extends ServiceImpl<SysBusinessEntityMapper, SysBusinessEntity> implements SysBusinessEntityService {

	private final SysCompanyInfoMapper sysCompanyInfoMapper;

	private final SysBusinessEntityMapper sysBusinessEntityMapper;

	private final SysMenuMapper sysMenuMapper;

	private final SysUserRoleScopeMapper sysUserRoleScopeMapper;

	private final SysRoleMenuMapper sysRoleMenuMapper;

	private final SysUserService sysUserService;

	private final IWarehouseProvider warehouseProvider;


	/**
	 * 公司名称map
	 */
	private static final Map<Long,String> siteComapnyNameMap=new ConcurrentHashMap<>();

	private final List<Long> siteScopeIds= Arrays.asList(ScopeEnum.SITE.getId());

	private final List<Long> wareHouseScopeIds= Arrays.asList(ScopeEnum.WAREHOUSE.getId());



	@Override
    public IPage<BusinessPageVO> getSysBusinessEntityPage(Page page, BusinessPageDTO dto) {
		dto.setTenantId(SecurityUtils.getUser().getTenantId());
		DataPermissionVO dataPermissionVO=sysUserService.getDataPermisston(CommonConstants.ZERO,MenuEnum.BASE_ORGANIZATION_BUSINESS.getCode(),siteScopeIds);
		dto.setSiteList(dataPermissionVO.getSiteList()).setAll(dataPermissionVO.getSiteAll());
		IPage<BusinessPageVO> iPageInfo =sysBusinessEntityMapper.selectPageInfo(page,dto);
		return iPageInfo;
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveBusiness(BusinessSaveDTO dto) {
		DaoismUser user = SecurityUtils.getUser();
		SysBusinessEntity sysBusinessEntity=BeanUtil.toBean(dto,SysBusinessEntity.class);
		if(ObjectUtil.isNotNull(dto.getBusinessId())){
			//查询公司名称是否存在
			Integer exist= sysBusinessEntityMapper.selectCount(Wrappers.<SysBusinessEntity>lambdaQuery().eq(SysBusinessEntity::getBusinessName,dto.getBusinessName())
				.eq(SysBusinessEntity::getDelFlag,CommonConstants.NOT_DEL).ne(SysBusinessEntity::getBusinessId,dto.getBusinessId())
				.eq(SysBusinessEntity::getTenantId,user.getTenantId())
			);
			if(exist>CommonConstants.ZERO){
				throw new BizException(ResultCodeEnum.BUSINESS_ENTITY_NAME_EXIST);
			}
			Integer codeExist= sysBusinessEntityMapper.selectCount(Wrappers.<SysBusinessEntity>lambdaQuery()
				.eq(SysBusinessEntity::getBusinessCode,dto.getBusinessCode()).eq(SysBusinessEntity::getTenantId,user.getTenantId())
				.eq(SysBusinessEntity::getDelFlag,CommonConstants.NOT_DEL).ne(SysBusinessEntity::getBusinessId,dto.getBusinessId()));
			if(codeExist>CommonConstants.ZERO){
				throw new BizException(100,"业务编码已存在!");
			}
			sysBusinessEntity.setUpdatedBy(user.getName()).setUpdateId(user.getId()).setUpdateTime(LocalDateTime.now());
			if(!updateById(sysBusinessEntity)){
				throw new BizException(ResultCodeEnum.DATA_SAVE_ERROR);
			}
		}else {
			//查询站点名称是否存在
			Integer exist= sysBusinessEntityMapper.selectCount(Wrappers.<SysBusinessEntity>lambdaQuery()
				.eq(SysBusinessEntity::getBusinessName,dto.getBusinessName()).eq(SysBusinessEntity::getTenantId,user.getTenantId())
				.eq(SysBusinessEntity::getDelFlag,CommonConstants.NOT_DEL));
			if(exist>CommonConstants.ZERO){
				throw new BizException(ResultCodeEnum.BUSINESS_ENTITY_NAME_EXIST);
			}
			Integer existCode= sysBusinessEntityMapper.selectCount(Wrappers.<SysBusinessEntity>lambdaQuery()
				.eq(SysBusinessEntity::getBusinessCode,dto.getBusinessCode()).eq(SysBusinessEntity::getTenantId,user.getTenantId())
				.eq(SysBusinessEntity::getDelFlag,CommonConstants.NOT_DEL));
			sysBusinessEntity.setCreateId(user.getId()).setCreatedBy(user.getName())
					.setCreateTime(LocalDateTime.now()).setTenantId(user.getTenantId()).setDelFlag(CommonConstants.NOT_DEL);

			if(!save(sysBusinessEntity)){
				throw new BizException(ResultCodeEnum.DATA_SAVE_ERROR);
			}
			//新增的站点加入数据权限
			//查询哪个角色公司设置的权限
			SysMenu sysMenu=sysMenuMapper.selectOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission, MenuEnum.BASE_ORGANIZATION_BUSINESS.getCode()));
			SecurityUtils.getRoles().forEach(item ->{
				SysRoleMenu sysRoleMenu=sysRoleMenuMapper.selectOne(Wrappers.<SysRoleMenu>lambdaQuery()
						.eq(SysRoleMenu::getRoleId,item).eq(SysRoleMenu::getMenuId,sysMenu.getMenuId()));
				if(ObjectUtil.isNotNull(sysRoleMenu)){
					SysUserRoleScope scope = sysUserRoleScopeMapper.selectOne(Wrappers.<SysUserRoleScope>lambdaQuery()
							.eq(SysUserRoleScope::getRoleId,item).eq(SysUserRoleScope::getUserId,user.getId())
							.eq(SysUserRoleScope::getScopeId, ScopeEnum.SITE.getId()));
					if(CommonConstants.ZERO.equals(scope.getAllFlag())){
						scope.setIds(scope.getIds()+","+sysBusinessEntity.getBusinessId());
						if(sysUserRoleScopeMapper.updateById(scope)==CommonConstants.ZERO){
							throw new BizException(ResultCodeEnum.DATA_SAVE_ERROR);
						}
					}
					//增加系统仓库
					List<Long> listR = warehouseProvider.initSiteWarehouse(sysBusinessEntity.getBusinessId()).getData();
					SysUserRoleScope wouseScope = sysUserRoleScopeMapper.selectOne(Wrappers.<SysUserRoleScope>lambdaQuery()
							.eq(SysUserRoleScope::getRoleId,item).eq(SysUserRoleScope::getUserId,user.getId())
							.eq(SysUserRoleScope::getScopeId, ScopeEnum.WAREHOUSE.getId()));
					if(CommonConstants.ZERO.equals(scope.getAllFlag())){
						wouseScope.setIds(CollectionUtil.join(listR,","));
						if(sysUserRoleScopeMapper.updateById(wouseScope)==CommonConstants.ZERO){
							throw new BizException(ResultCodeEnum.DATA_SAVE_ERROR);
						}
					}
				}
			});
			//todo :增加仓库
		}
		return Boolean.TRUE;
	}

	@Override
	public BusinessPageVO getSysBusinessDetail(Long businessId) {
		SysBusinessEntity sysBusinessEntity=sysBusinessEntityMapper.selectById(businessId);
		BusinessPageVO vo = BeanUtil.toBean(sysBusinessEntity, BusinessPageVO.class);
		SysCompanyInfo sysCompanyInfo = sysCompanyInfoMapper.selectById(sysBusinessEntity.getCompanyId());
		vo.setCompanyName(sysCompanyInfo.getCompanyName());
		return vo;
	}

    @Override
    public SiteInfoVO getSiteInfoById(Long siteId) {
		SysBusinessEntity sysBusinessEntity=sysBusinessEntityMapper.selectById(siteId);
		if(ObjectUtil.isNotNull(sysBusinessEntity)){
			SiteInfoVO vo=new SiteInfoVO();
			vo.setSiteId(sysBusinessEntity.getBusinessId());
			vo.setCompanyId(sysBusinessEntity.getCompanyId());
			SysCompanyInfo sysCompanyInfo = sysCompanyInfoMapper.selectById(sysBusinessEntity.getCompanyId());
			vo.setSiteName(sysCompanyInfo.getCompanyName()+'-'+sysBusinessEntity.getBusinessName());
			vo.setCompanyName(sysCompanyInfo.getCompanyName());
			return vo;
		}
		return null;
    }

    @Override
    public List<WarehouseFeignVO> getWarehouseList(String menuCode,Long siteId) {
		DataPermissionVO dataPermissionVO=sysUserService.getDataPermisston(CommonConstants.ONE,menuCode,wareHouseScopeIds);
		DataPermissionDTO dto=new DataPermissionDTO();
		if(ObjectUtil.isNotNull(siteId)){
			dto.setSiteId(siteId);
		}
		dto.setAllFlag(dataPermissionVO.getWarehouseAll());
		dto.setIds(dataPermissionVO.getWarehouseList());
		dto.setTenantId(SecurityUtils.getUser().getTenantId());
		List<WarehouseFeignVO> list = warehouseProvider.getDataPermWarehouse(dto).getData();
		return list;
    }

    @Override
	public R<Boolean> removeSite(DeleteDto dto) {
		DaoismUser user = SecurityUtils.getUser();
		dto.getIds().forEach(item ->{
			SysBusinessEntity sysBusinessEntity =new SysBusinessEntity();
			sysBusinessEntity.setBusinessId(item).setDelFlag(CommonConstants.ONE)
					.setUpdateId(user.getId()).setUpdatedBy(user.getName()).setUpdateTime(LocalDateTime.now());
			if(!updateById(sysBusinessEntity)){
				throw new BizException(ResultCodeEnum.DATA_SAVE_ERROR);
			}
		});
		return R.ok(Boolean.TRUE);
	}

    @Override
    public List<SiteInfoVO> getSiteInfo(String menuCode) {
		DataPermissionVO dataPermissionVO=sysUserService.getDataPermisston(CommonConstants.ONE,menuCode,siteScopeIds);
		List<SiteInfoVO> list=new ArrayList<>();
		List<SysBusinessEntity> sysBusinessEntities = sysBusinessEntityMapper.selectList(Wrappers.<SysBusinessEntity>lambdaQuery()
				.eq(SysBusinessEntity::getTenantId,SecurityUtils.getUser().getTenantId())
				.in(!dataPermissionVO.getSiteAll(),SysBusinessEntity::getBusinessId,dataPermissionVO.getSiteList()));
		sysBusinessEntities.forEach(item ->{
			SiteInfoVO vo=new SiteInfoVO();
			vo.setSiteId(item.getBusinessId());
			vo.setSiteCode(item.getBusinessCode());
			vo.setCompanyId(item.getCompanyId());
			if(siteComapnyNameMap.containsKey(item.getCompanyId())){
				vo.setSiteName(siteComapnyNameMap.get(item.getCompanyId())+'-'+item.getBusinessName());
				vo.setCompanyName(siteComapnyNameMap.get(item.getCompanyId()));
			}else {
				SysCompanyInfo sysCompanyInfo = sysCompanyInfoMapper.selectById(item.getCompanyId());
				siteComapnyNameMap.put(item.getCompanyId(),sysCompanyInfo.getCompanyName());
				vo.setSiteName(sysCompanyInfo.getCompanyName()+'-'+item.getBusinessName());
				vo.setCompanyName(sysCompanyInfo.getCompanyName());
			}
			list.add(vo);
		});
		return list;
    }


}
